package com.nofeng.wx.third;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.nofeng.wx.utils.BaseUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class EastMoneyStockApi {

    public static String ETF500="000009,000021,000027,000032,000034,000039,000050,000060,000062,000066,000155,000400,000403,000415,000423,000426,000429,000513,000519,000528,000537,000539,000543,000559,000563,000582,000591,000598,000623,000629,000636,000683,000703,000709,000723,000728,000729,000733,000738,000739,000750,000783,000785,000825,000830,000831,000878,000883,000887,000893,000898,000921,000932,000933,000937,000951,000958,000959,000960,000967,000987,000988,000997,001213,001286,001389,001696,002007,002008,002025,002044,002056,002064,002065,002078,002080,002085,002120,002130,002138,002152,002153,002155,002156,002185,002195,002202,002203,002223,002244,002261,002262,002266,002273,002281,002294,002299,002312,002318,002340,002353,002372,002385,002409,002410,002414,002423,002429,002430,002432,002436,002439,002444,002461,002465,002472,002500,002507,002508,002517,002532,002558,002563,002568,002572,002595,002603,002607,002608,002624,002653,002670,002673,002683,002738,002739,002756,002773,002797,002821,002831,002837,002841,002850,002851,002926,002939,002945,002958,002966,002984,003022,003031,003035,300001,300002,300003,300012,300017,300024,300037,300054,300058,300070,300073,300115,300136,300140,300142,300144,300146,300207,300212,300223,300251,300285,300339,300346,300373,300383,300390,300395,300450,300454,300458,300474,300476,300487,300496,300529,300558,300567,300573,300595,300601,300604,300623,300627,300676,300677,300679,300699,300724,300735,300748,300751,300757,300763,300765,300803,300857,300888,300919,300957,301165,301267,301301,301308,301358,301498,301536,600004,600007,600008,600021,600032,600038,600056,600060,600062,600079,600095,600096,600098,600109,600118,600126,600131,600132,600141,600143,600153,600155,600157,600166,600170,600171,600177,600208,600258,600271,600282,600295,600298,600299,600312,600316,600325,600329,600339,600348,600352,600361,600363,600369,600373,600378,600380,600390,600392,600398,600435,600483,600486,600487,600497,600498,600499,600511,600516,600517,600521,600528,600529,600535,600536,600546,600549,600562,600563,600566,600578,600580,600582,600583,600598,600606,600612,600637,600655,600663,600673,600685,600688,600699,600704,600707,600720,600737,600739,600754,600763,600764,600765,600801,600808,600816,600820,600839,600848,600859,600862,600863,600867,600871,600872,600873,600879,600884,600885,600895,600901,600906,600909,600925,600927,600928,600956,600959,600968,600970,600977,600985,600988,600995,600998,601000,601001,601016,601019,601061,601098,601099,601106,601108,601118,601128,601139,601155,601156,601158,601162,601168,601179,601198,601212,601216,601228,601231,601233,601333,601399,601456,601555,601568,601577,601598,601608,601611,601615,601636,601665,601666,601696,601717,601858,601866,601880,601918,601921,601928,601933,601958,601965,601966,601990,601991,601997,603000,603077,603087,603129,603156,603160,603179,603225,603228,603233,603290,603298,603338,603341,603345,603379,603486,603529,603556,603565,603568,603589,603596,603605,603606,603650,603658,603659,603688,603707,603728,603737,603786,603816,603826,603858,603868,603885,603893,603899,603927,603939,603979,605358,605589,688002,688017,688027,688032,688052,688065,688072,688099,688100,688114,688120,688122,688153,688172,688180,688183,688188,688213,688220,688234,688235,688248,688249,688278,688281,688295,688297,688301,688318,688349,688361,688363,688375,688385,688387,688425,688469,688475,688520,688521,688525,688538,688561,688563,688568,688578,688582,688608,688617,688676,688702,688728,688772,688777,688778,688819,689009";

    private final CloseableHttpClient httpClient = HttpClients.createDefault();
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private final DateTimeFormatter apiFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");

    // 定义股票数据结构
    public static class EastmoneyStock {
        private String time;
        private Double open;
        private Double close;
        private Double high;
        private Double low;
        private Double volume;
        private Double amount;
        private Double changePercent;
        private Double changeAmount;
        private Double amplitude;
        private Double turnoverRate;

        public String getTime() {
            return time;
        }

        public void setTime(String time) {
            this.time = time;
        }

        public Double getOpen() {
            return open;
        }

        public void setOpen(Double open) {
            this.open = open;
        }

        public Double getClose() {
            return close;
        }

        public void setClose(Double close) {
            this.close = close;
        }

        public Double getHigh() {
            return high;
        }

        public void setHigh(Double high) {
            this.high = high;
        }

        public Double getLow() {
            return low;
        }

        public void setLow(Double low) {
            this.low = low;
        }

        public Double getVolume() {
            return volume;
        }

        public void setVolume(Double volume) {
            this.volume = volume;
        }

        public Double getAmount() {
            return amount;
        }

        public void setAmount(Double amount) {
            this.amount = amount;
        }

        public Double getChangePercent() {
            return changePercent;
        }

        public void setChangePercent(Double changePercent) {
            this.changePercent = changePercent;
        }

        public Double getChangeAmount() {
            return changeAmount;
        }

        public void setChangeAmount(Double changeAmount) {
            this.changeAmount = changeAmount;
        }

        public Double getAmplitude() {
            return amplitude;
        }

        public void setAmplitude(Double amplitude) {
            this.amplitude = amplitude;
        }

        public Double getTurnoverRate() {
            return turnoverRate;
        }

        public void setTurnoverRate(Double turnoverRate) {
            this.turnoverRate = turnoverRate;
        }
    }

    public static Map<String,Integer>  getCount() throws IOException {
        String url="https://push2.eastmoney.com/api/qt/ulist/get?fltt=1&invt=2&cb=a&fields=f12%2Cf13%2Cf14%2Cf1%2Cf2%2Cf4%2Cf3%2Cf152%2Cf6%2Cf104%2Cf105%2Cf106&secids=1.000001%2C0.399001&ut=fa5fd1943c7b386f172d6893dbfba10b&pn=1&np=1&pz=20&dect=1&wbp2u=%7C0%7C0%7C0%7Cweb&_=";
        url+= System.currentTimeMillis();
        HttpGet request = new HttpGet(url);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            String jsonResponse = EntityUtils.toString(response.getEntity());
            jsonResponse= StringUtils.replace(jsonResponse,"a(","");
            jsonResponse=StringUtils.substringBeforeLast(jsonResponse,")");
            JSONObject jsonObject=JSONObject.parseObject(jsonResponse);
            JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("diff");
            Integer up = 0;
            Integer eq = 0;
            Integer down = 0;
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject o = jsonArray.getJSONObject(i);
                up += o.getInteger("f104");
                eq += o.getInteger("f106");
                down += o.getInteger("f105");
            }
            Map<String,Integer> map= Maps.newHashMap();
            map.put("up",up);
            map.put("eq",eq);
            map.put("down",down);
            return map;
        }

    }

    public static JSONArray getStockK(String symbol,String begin) throws IOException {
        String secid = getSecId(symbol);
        String url="https://push2his.eastmoney.com/api/qt/stock/kline/get?fields1=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13&fields2=f20,f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61&beg="+begin+"&end=20500101&ut=fa5fd1943c7b386f172d6893dbfba10b&rtntype=6&klt=101&fqt=1&cb=a";
        url+="&secid="+secid;
        url+="&_=" + System.currentTimeMillis();
        HttpGet request = new HttpGet(url);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            String jsonResponse = EntityUtils.toString(response.getEntity());
            jsonResponse= StringUtils.replace(jsonResponse,"a(","");
            jsonResponse=StringUtils.substringBeforeLast(jsonResponse,")");
            JSONObject jsonObject=JSONObject.parseObject(jsonResponse);
            JSONObject data = jsonObject.getJSONObject("data");
            if(null!=data) {
                JSONArray jsonArray = data.getJSONArray("klines");
                return jsonArray;
            }
        }
        return JSONArray.parseArray("[]");
    }
    public List<EastmoneyStock> getStockHistory(
            String symbol,
            String startDate,
            String endDate,
            String period,
            String adjust) throws Exception {

        // 构建请求URL
        String url = buildUrl(symbol, startDate, endDate, period, adjust);
        HttpGet request = new HttpGet(url);

        try (CloseableHttpResponse response = httpClient.execute(request)) {
            String jsonResponse = EntityUtils.toString(response.getEntity());
            return parseResponse(jsonResponse, period);
        }
    }

    public static JSONArray getNews(Set<String> time)throws Exception{
        {
            long timeMillis = System.currentTimeMillis();
            String url = "https://np-weblist.eastmoney.com/comm/web/getFastNewsList?client=web&biz=web_724&fastColumn=101&sortEnd=&pageSize=500&req_trace=" + timeMillis + "&_=" + timeMillis + "&callback=a";
            HttpGet request = new HttpGet(url);
            CloseableHttpClient httpClient = HttpClients.createDefault();
            try (CloseableHttpResponse response = httpClient.execute(request)) {
                String jsonResponse = EntityUtils.toString(response.getEntity());
                jsonResponse= StringUtils.replace(jsonResponse,"a(","");
                jsonResponse=StringUtils.substringBeforeLast(jsonResponse,")");
                JSONObject jsonObject = JSONObject.parseObject(jsonResponse);
                JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("fastNewsList");
                JSONArray jsonResult=JSONArray.parseArray("[]");
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject newsJSON = jsonArray.getJSONObject(i);
                    String dataTime = StringUtils.replace(newsJSON.getString("showTime"), "-", "").split(" ")[0];
                    if(time.contains(dataTime)) {
                        String code = newsJSON.getString("code");
                        newsJSON.put("url", "https://finance.eastmoney.com/a/" + code + ".html");
                        JSONArray stockList = newsJSON.getJSONArray("stockList");
                        List<String> bkList = Lists.newArrayList();
                        for (int j = 0; j < stockList.size(); j++) {
                            String bk = stockList.getString(j);
                            if (bk.contains("BK")) {
                                bkList.add(bk);
                            }
                        }
                        newsJSON.put("bkList", bkList);
                        jsonResult.add(newsJSON);
                    }

                }
                return jsonResult;
            }
        }

    }

    //上证流入历史
    public static JSONArray get0000VolumeHistory(Integer lmt)throws Exception {
        long timeMillis = System.currentTimeMillis();
        String url = "https://push2his.eastmoney.com/api/qt/stock/fflow/daykline/get?cb=a&lmt=#lmt&klt=101&fields1=f1%2Cf2%2Cf3%2Cf7&fields2=f51%2Cf52%2Cf53%2Cf54%2Cf55%2Cf56%2Cf57%2Cf58%2Cf59%2Cf60%2Cf61%2Cf62%2Cf63%2Cf64%2Cf65&ut=#t&secid=1.000001&secid2=0.399001&_=#t";
        url = StringUtils.replace(url, "#t", timeMillis + "");
        url = StringUtils.replace(url, "#lmt", lmt + "");
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet request = new HttpGet(url);
        JSONArray jsonResult=JSONArray.parseArray("[]");
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            String jsonResponse = EntityUtils.toString(response.getEntity());
            jsonResponse= StringUtils.replace(jsonResponse,"a(","");
            jsonResponse=StringUtils.substringBeforeLast(jsonResponse,")");
            JSONObject jsonObject=JSONObject.parseObject(jsonResponse);
            JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("klines");
            for (int i = 0; i < jsonArray.size(); i++) {
                String d = jsonArray.getString(i);
                String[] dSplit = StringUtils.split(d, ",");
                String date = dSplit[0];
                String volume = dSplit[1];
                String chp = dSplit[12];
                JSONObject formatedData = JSONObject.parseObject("{}");
                formatedData.put("date",date);
                formatedData.put("volume",volume);
                formatedData.put("chp",chp);
                formatedData.put("buy","0");
                jsonResult.add(formatedData);
            }

            int holdDay=3;

            // 2. 遍历数据并筛选符合条件的记录
            for (int i = holdDay-1; i < jsonResult.size(); i++) { // 从第3天开始（需前两日数据）
                JSONObject today = jsonResult.getJSONObject(i);
                JSONObject prev1 = jsonResult.getJSONObject(i - 1);
                JSONObject prev2 = jsonResult.getJSONObject(i - 2);

                // 解析数据
                String date = today.getString("date");
                double inflow = today.getDouble("volume") / 1e8; // 转换为亿
                double outflow1 = prev1.getDouble("volume") / 1e8;
                double outflow2 = prev2.getDouble("volume") / 1e8;
                double todayChp = today.getDouble("chp");

                // 条件过滤：流入>20亿、前两日流出均<-100亿、当日涨幅<3%
                if (inflow > 20 && inflow<100 && outflow1 +outflow2< -200 && todayChp < 3) {
                    today.put("buy","1");
                }else{
                    today.put("buy","0");
                }
            }
            return jsonResult;
        }
    }
    //板块流入历史
    public static JSONArray getIndustryHistory(String industry) throws Exception{
        long timeMillis = System.currentTimeMillis();
        String url = "https://push2his.eastmoney.com/api/qt/stock/kline/get?cb=a&secid=90.#industry&ut=#t&fields1=f1%2Cf2%2Cf3%2Cf4%2Cf5%2Cf6&fields2=f51%2Cf52%2Cf53%2Cf54%2Cf55%2Cf56%2Cf57%2Cf58%2Cf59%2Cf60%2Cf61&klt=101&fqt=1&end=20500101&lmt=365&_=#t";
        url = StringUtils.replace(url, "#t", timeMillis + "");
        url = StringUtils.replace(url, "#industry", industry);

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet request = new HttpGet(url);
        JSONArray jsonResult=JSONArray.parseArray("[]");
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            String jsonResponse = EntityUtils.toString(response.getEntity());
            jsonResponse= StringUtils.replace(jsonResponse,"a(","");
            jsonResponse=StringUtils.substringBeforeLast(jsonResponse,")");
            JSONObject jsonObject=JSONObject.parseObject(jsonResponse);
            JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("klines");
            for (int i = 0; i < jsonArray.size(); i++) {
                String d = jsonArray.getString(i);
                String[] dSplit = StringUtils.split(d, ",");
                String date = dSplit[0];
                String volume = dSplit[5];
                String chp = dSplit[8];
                JSONObject formatedData = JSONObject.parseObject("{}");
                formatedData.put("date",date);
                formatedData.put("volume",volume);
                formatedData.put("chp",chp);
                jsonResult.add(formatedData);
            }
            return jsonResult;
        }
    }



    //https://data.eastmoney.com/bkzj/hy.html
    public static JSONArray getHotIndustry(Integer day) throws Exception {

        //f62今日f267三天//f164五天
        String f="f62";
        if(day.equals(3)){
            f="f267";
        }else if(day.equals(5)){
            f="f164";
        }else if(day.equals(10)){
            f="f174";
        }
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 构建请求URL
        String url = "https://data.eastmoney.com/dataapi/bkzj/getbkzj?key="+f+"&code=m%3A90%2Bt%3A2";

        HttpGet request = new HttpGet(url);

        try (CloseableHttpResponse response = httpClient.execute(request)) {
            String jsonResponse = EntityUtils.toString(response.getEntity());
            JSONObject jsonObject=JSONObject.parseObject(jsonResponse);
            JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("diff");
            return jsonArray;
        }
    }

    public static JSONArray  getHotIndustryDetail(String bk)throws Exception{
        String url="https://push2.eastmoney.com/api/qt/clist/get?cb=a&fid=f62&po=1&pz=50&pn=1&np=1&fltt=2&invt=2&ut=8dec03ba335b81bf4ebdf7b29ec27d15&fs=b%3A"+bk+"&fields=f62%2Cf9%2Cf24%2Cf7%2Cf12%2Cf14%2Cf2%2Cf3%2Cf62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf204%2Cf205%2Cf124%2Cf1%2Cf13";
        HttpGet request = new HttpGet(url);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            String jsonResponse = EntityUtils.toString(response.getEntity());
            jsonResponse= StringUtils.replace(jsonResponse,"a(","");
            jsonResponse=StringUtils.substringBeforeLast(jsonResponse,")");
            JSONObject jsonObject=JSONObject.parseObject(jsonResponse);
            JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("diff");
            return jsonArray;
        }
    }

    public static JSONArray getHotStock(Integer day) throws Exception {

        //f62今日f267三天//f164五天
        String f="f62";
        if(day.equals(3)){
            f="f267";
        }else if(day.equals(5)){
            f="f164";
        }else if(day.equals(10)){
            f="f174";
        }
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 构建请求URL
        String url = "https://push2.eastmoney.com/api/qt/clist/get?cb=a=&fid="+f+"&po=1&pz=50&pn=1&np=1&fltt=2&invt=2&ut=8dec03ba335b81bf4ebdf7b29ec27d15&fs=m%3A0%2Bt%3A6%2Bf%3A!2%2Cm%3A0%2Bt%3A13%2Bf%3A!2%2Cm%3A0%2Bt%3A80%2Bf%3A!2%2Cm%3A1%2Bt%3A2%2Bf%3A!2%2Cm%3A1%2Bt%3A23%2Bf%3A!2%2Cm%3A0%2Bt%3A7%2Bf%3A!2%2Cm%3A1%2Bt%3A3%2Bf%3A!2&fields=f12%2Cf14%2Cf2%2Cf3%2Cf62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf204%2Cf205%2Cf124%2Cf1%2Cf13";
        HttpGet request = new HttpGet(url);

        try (CloseableHttpResponse response = httpClient.execute(request)) {
            String jsonResponse = EntityUtils.toString(response.getEntity());
            jsonResponse= StringUtils.replace(jsonResponse,"a=(","");
            jsonResponse=StringUtils.substringBeforeLast(jsonResponse,")");
            JSONObject jsonObject=JSONObject.parseObject(jsonResponse);
            JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("diff");
            return jsonArray;
        }
    }

    private String buildUrl(String symbol, String start, String end, String period, String adjust) {
        Map<String, String> adjustMap = BaseUtils.mapOf("", "0", "qfq", "1", "hfq", "2");
        String secid = getSecId(symbol);

        // 转换时间格式
        String startTime = LocalDateTime.parse(start, inputFormatter).format(apiFormatter);
        String endTime = LocalDateTime.parse(end, inputFormatter).format(apiFormatter);

        if ("1".equals(period)) {
            return "https://push2his.eastmoney.com/api/qt/stock/trends2/get" +
                    "?fields1=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13" +
                    "&fields2=f51,f52,f53,f54,f55,f56,f57,f58" +
                    "&ut=7eea3edcaed734bea9cbfc24409ed989" +
                    "&ndays=20" +
                    "&iscr=0" +
                    "&secid=" + secid +
                    "&_=" + System.currentTimeMillis();
        } else {
            return "http://push2his.eastmoney.com/api/qt/stock/kline/get" +
                    "?fields1=f1,f2,f3,f4,f5,f6" +
                    "&fields2=f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61" +
                    "&ut=7eea3edcaed734bea9cbfc24409ed989" +
                    "&klt=" + period +
                    "&fqt=" + adjustMap.getOrDefault(adjust, "0") +
                    "&secid=" + secid +
                    "&beg=" + startTime +
                    "&end=" + endTime +
                    "&_=" + System.currentTimeMillis();
        }
    }

    public static String getSecId(String symbol) {
        // 根据股票代码确定市场类型
        char firstChar = symbol.charAt(0);
        if (firstChar == '6') return "1." + symbol;   // 沪市
        if (firstChar == '0' || firstChar == '3') return "0." + symbol; // 深市
        return "0." + symbol; // 默认深市
    }

    private List<EastmoneyStock> parseResponse(String jsonResponse, String period) throws Exception {
        JsonNode rootNode = objectMapper.readTree(jsonResponse);
        JsonNode dataNode = rootNode.path("data");
        List<EastmoneyStock> result = new ArrayList<>();

        if ("1".equals(period)) {
            JsonNode trends = dataNode.path("trends");
            for (JsonNode item : trends) {
                String[] values = item.asText().split(",");
                if (values.length < 8) continue;

                EastmoneyStock stock = new EastmoneyStock();
                stock.setTime(values[0]);
                stock.setOpen(parseDouble(values[1]));
                stock.setClose(parseDouble(values[2]));
                stock.setHigh(parseDouble(values[3]));
                stock.setLow(parseDouble(values[4]));
                stock.setVolume(parseDouble(values[5]));
                stock.setAmount(parseDouble(values[6]));
                // 1分钟线无以下字段
                result.add(stock);
            }
        } else {
            JsonNode klines = dataNode.path("klines");
            for (JsonNode item : klines) {
                String[] values = item.asText().split(",");
                if (values.length < 11) continue;

                EastmoneyStock stock = new EastmoneyStock();
                stock.setTime(values[0]);
                stock.setOpen(parseDouble(values[1]));
                stock.setClose(parseDouble(values[2]));
                stock.setHigh(parseDouble(values[3]));
                stock.setLow(parseDouble(values[4]));
                stock.setVolume(parseDouble(values[5]));
                stock.setAmount(parseDouble(values[6]));
                stock.setAmplitude(parseDouble(values[7]));
                stock.setChangePercent(parseDouble(values[8]));
                stock.setChangeAmount(parseDouble(values[9]));
                stock.setTurnoverRate(parseDouble(values[10]));
                result.add(stock);
            }
        }
        return result;
    }

    private Double parseDouble(String value) {
        try {
            return Double.parseDouble(value);
        } catch (NumberFormatException e) {
            return 0.0;
        }
    }
}